package fr.thelem.gestiondemandesthelem.web.adminactions;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.springframework.security.core.context.SecurityContextHolder;

import fr.thelem.gestiondemandesthelem.dao.model.CPDemandeEntity;
import fr.thelem.gestiondemandesthelem.dao.model.CPEtapeEntity;
import fr.thelem.gestiondemandesthelem.dao.model.CPPointDeControleEntity;
import fr.thelem.gestiondemandesthelem.dao.model.CommentairesEntity;
import fr.thelem.gestiondemandesthelem.dao.model.EtatEntity;
import fr.thelem.gestiondemandesthelem.dao.model.PersonneEntity;
import fr.thelem.gestiondemandesthelem.service.IAppliService;
import fr.thelem.gestiondemandesthelem.web.actions.BaseAction;
import fr.thelem.gestiondemandesthelem.web.commons.SauvegardeXML;

/**
 *
 */
public class ConsulterDemandeAction extends BaseAction {

    /** Attribut serialVersionUID */
    private static final long serialVersionUID = 1L;

    private IAppliService appliService;

    private String idDemande;
    private Map sauvegarder = new HashMap(); /* corresponds au bouton sauvegarder dans consultDemande.jsp */
    private List<CPPointDeControleEntity> ListPointControle;
    private Map pointTextField = new HashMap();
    private Map pointCheckBox = new HashMap();
    private CPDemandeEntity CPDemande;
    private CPDemandeEntity CPDemandeWithEtape;
    private String etat;
    private Collection<String> lesetats = new ArrayList<String>(); // supprimer le new si on ne rappel la fonction de recupération
    private String etatDemande;
    private List<String> Letats = new ArrayList<String>();
    private Map ModifierEtatConsult = new HashMap(); /* corresponds au bouton ModifierEtatConsult dans consultDemande.jsp */
    private Map modifierEtatDeDemande = new HashMap();
    private String reference;
    private boolean typeReference;
    private String EtapeChoisit;
    private String idCommentaire;
    private String CommentaireDemande;
    private Collection<CommentairesEntity> lesCommentaires;

    /** json **/
    private String idCPDemande;
    private SauvegardeXML SauvegardeXML;

    /**
     * Accesseur de idCPDemande
     * 
     * @return le idCPDemande
     */
    public String getIdCPDemande() {
        return idCPDemande;
    }

    /**
     * Affectation de idCPDemande
     * 
     * @param idCPDemande idCPDemande à affecter
     */
    public void setIdCPDemande(String idCPDemande) {
        this.idCPDemande = idCPDemande;
    }

    /**
     * Accesseur de sauvegardeXML
     * 
     * @return le sauvegardeXML
     */
    public SauvegardeXML getSauvegardeXML() {
        return SauvegardeXML;
    }

    /**
     * Affectation de sauvegardeXML
     * 
     * @param sauvegardeXML sauvegardeXML à affecter
     */
    public void setSauvegardeXML(SauvegardeXML sauvegardeXML) {
        SauvegardeXML = sauvegardeXML;
    }

    /**
     * Accesseur de appliService
     * 
     * @return le appliService
     */
    public IAppliService getAppliService() {
        return appliService;
    }

    /**
     * Affectation de appliService
     * 
     * @param appliService appliService à affecter
     */
    public void setAppliService(IAppliService appliService) {
        this.appliService = appliService;
    }

    /**
     * Accesseur de idDemande
     * 
     * @return le idDemande
     */
    public String getIdDemande() {
        return idDemande;
    }

    /**
     * Affectation de idDemande
     * 
     * @param idDemande idDemande à affecter
     */
    public void setIdDemande(String idDemande) {
        this.idDemande = idDemande;
    }

    /**
     * Accesseur de sauvegarder
     * 
     * @return le sauvegarder
     */
    public Map getSauvegarder() {
        return sauvegarder;
    }

    /**
     * Affectation de sauvegarder
     * 
     * @param sauvegarder sauvegarder à affecter
     */
    public void setSauvegarder(Map sauvegarder) {
        this.sauvegarder = sauvegarder;
    }

    /**
     * Accesseur de listPointControle
     * 
     * @return le listPointControle
     */
    public List<CPPointDeControleEntity> getListPointControle() {
        return ListPointControle;
    }

    /**
     * Affectation de listPointControle
     * 
     * @param listPointControle listPointControle à affecter
     */
    public void setListPointControle(List<CPPointDeControleEntity> listPointControle) {
        ListPointControle = listPointControle;
    }

    /**
     * Accesseur de pointTextField
     * 
     * @return le pointTextField
     */
    public Map getPointTextField() {
        return pointTextField;
    }

    /**
     * Affectation de pointTextField
     * 
     * @param pointTextField pointTextField à affecter
     */
    public void setPointTextField(Map pointTextField) {
        this.pointTextField = pointTextField;
    }

    /**
     * Accesseur de checkBox
     * 
     * @return le checkBox
     */
    public Map getPointCheckBox() {
        return pointCheckBox;
    }

    /**
     * Affectation de checkBox
     * 
     * @param checkBox checkBox à affecter
     */
    public void setPointCheckBox(Map pointCheckBox) {
        this.pointCheckBox = pointCheckBox;
    }

    /**
     * Accesseur de cPDemande
     * 
     * @return le cPDemande
     */
    public CPDemandeEntity getCPDemande() {
        return CPDemande;
    }

    /**
     * Affectation de cPDemande
     * 
     * @param cPDemande cPDemande à affecter
     */
    public void setCPDemande(CPDemandeEntity cPDemande) {
        CPDemande = cPDemande;
    }

    /**
     * Accesseur de cPDemandeWithEtape
     * 
     * @return le cPDemandeWithEtape
     */
    public CPDemandeEntity getCPDemandeWithEtape() {
        return CPDemandeWithEtape;
    }

    /**
     * Affectation de cPDemandeWithEtape
     * 
     * @param cPDemandeWithEtape cPDemandeWithEtape à affecter
     */
    public void setCPDemandeWithEtape(CPDemandeEntity cPDemandeWithEtape) {
        CPDemandeWithEtape = cPDemandeWithEtape;
    }

    /**
     * Accesseur de etat
     * 
     * @return le etat
     */
    public String getEtat() {
        return etat;
    }

    /**
     * Affectation de etat
     * 
     * @param etat etat à affecter
     */
    public void setEtat(String etat) {
        this.etat = etat;
    }

    /**
     * Accesseur de lesetats
     * 
     * @return le lesetats
     */
    public Collection<String> getLesetats() {
        return lesetats;
    }

    /**
     * Affectation de lesetats
     * 
     * @param lesetats lesetats à affecter
     */
    public void setLesetats(Collection<String> lesetats) {
        this.lesetats = lesetats;
    }

    /**
     * Accesseur de etatDemande
     * 
     * @return le etatDemande
     */
    public String getEtatDemande() {
        return etatDemande;
    }

    /**
     * Affectation de etatDemande
     * 
     * @param etatDemande etatDemande à affecter
     */
    public void setEtatDemande(String etatDemande) {
        this.etatDemande = etatDemande;
    }

    /**
     * Accesseur de letats
     * 
     * @return le letats
     */
    public List<String> getLetats() {
        return Letats;
    }

    /**
     * Affectation de letats
     * 
     * @param letats letats à affecter
     */
    public void setLetats(List<String> letats) {
        Letats = letats;
    }

    /**
     * Accesseur de modifierEtatDeConsult
     * 
     * @return le modifierEtatDeConsult
     */
    public Map getModifierEtatDeDemande() {
        return modifierEtatDeDemande;
    }

    /**
     * Affectation de modifierEtatDeConsult
     * 
     * @param modifierEtatDeConsult modifierEtatDeConsult à affecter
     */
    public void setModifierEtatDeDemande(Map modifierEtatDeDemande) {
    	modifierEtatDeDemande = modifierEtatDeDemande;
    }

    /**
     * Accesseur de modifierEtatConsult
     * 
     * @return le modifierEtatConsult
     */
    public Map getModifierEtatConsult() {
        return ModifierEtatConsult;
    }

    /**
     * Affectation de modifierEtatConsult
     * 
     * @param modifierEtatConsult modifierEtatConsult à affecter
     */
    public void setModifierEtatConsult(Map modifierEtatConsult) {
        ModifierEtatConsult = modifierEtatConsult;
    }

    public String getReference() {
        return reference;
    }

    public void setReference(String reference) {
        this.reference = reference;
    }

    public boolean isTypeReference() {
        return typeReference;
    }

    public void setTypeReference(boolean typeReference) {
        this.typeReference = typeReference;
    }
    
    public Collection<CommentairesEntity> getLesCommentaires() {
		return lesCommentaires;
	}

	public void setLesCommentaires(Collection<CommentairesEntity> lesCommentaires) {
		this.lesCommentaires = lesCommentaires;
	}

    public String getIdCommentaire() {
		return idCommentaire;
	}

	public void setIdCommentaire(String idCommentaire) {
		this.idCommentaire = idCommentaire;
	}

	public String getCommentaireDemande() {
		return CommentaireDemande;
	}

	public void setCommentaireDemande(String commentaireDemande) {
		CommentaireDemande = commentaireDemande;
	}

	public String getEtapeChoisit() {
		return EtapeChoisit;
	}

	public void setEtapeChoisit(String etapeChoisit) {
		EtapeChoisit = etapeChoisit;
	}

	/**
     * Affichage de la jsp consultDemande avec toutes les informations requises
     * 
     * @return
     * @throws Exception
     */
    public String execute() throws Exception {
        this.ajouterRoleSession();
        initialiser();

        return SUCCESS;
    }

    /**
     * Modification et sauvegarde des points de contrôle de la demande
     * 
     * @return
     * @throws Exception
     */

    public String sauvegarderPointsControle() throws Exception {
    	int compteur=0;
    	int compteur2=0;
    	
        for (Iterator i = sauvegarder.keySet().iterator(); i.hasNext();) {
            int idDemande = Integer.valueOf((String) i.next());
            
           // il faut modifier le point de controle d'une demande pas de toute !!! 
           
            // cas de sauvegarde d'un point de contrôle de type input
            Set<Entry<String, Object>> mapSet = pointTextField.entrySet();
            for (Entry<String, Object> entry : mapSet) {
                String[] value = (String[]) entry.getValue();
                for (int u = 0; u < value.length; u++) {
                    if (!value[u].isEmpty()) {
                        appliService.modifierValeurPointControle(Integer.valueOf(entry.getKey()), value[u]);
                        appliService.modifierDateDernierEtatDemande(idDemande);
                        compteur++;
                    }
                    compteur2++;
                }
            }
            
            // cas de sauvegarde d'un point de contrôle de type checkbox
            Set<Entry<String, Object>> mapSetChek = pointCheckBox.entrySet();
            for (Entry<String, Object> entryCheck : mapSetChek) {
                String[] value = (String[]) entryCheck.getValue();
                for (int u = 0; u < value.length; u++) {
                    if (!value[u].equals("unchecked")) {
                        appliService.modifierValeurPointControle(Integer.valueOf(entryCheck.getKey()), "true");
                        appliService.modifierDateDernierEtatDemande(idDemande);
                        compteur++;
                    } else {
                        appliService.modifierValeurPointControle(Integer.valueOf(entryCheck.getKey()), "false");
                        appliService.modifierDateDernierEtatDemande(idDemande);
                        
                    }
                }
                compteur2++;
                
            }
            CPDemande = appliService.recupererCPDemandeById(idDemande);
            // workflow numéro 3
            if (compteur >= 1 && compteur < compteur2  ) {
            	if ( CPDemande.getEtatCPDemande().getNomEtat().equals("Ouverte") || CPDemande.getEtatCPDemande().getNomEtat().equals("Ré-ouverte")){
            		appliService.modifierEtatDemande(idDemande, "En attente");
                	appliService.modifierDateDernierEtatDemande(idDemande);
            	}
            }
            
            // workflow numéro 5 
            if (compteur == compteur2) {
            	appliService.modifierEtatDemande(idDemande, "En cours de traitement");
            	appliService.modifierDateDernierEtatDemande(idDemande);
            }
            
            
        }

        
        
        // remplir la jsp après sauvegarde de point de controle
        initialiser();
        return SUCCESS;
    }
    
    /**
     * Supprimer un commentaire
     * 
     * @return
     * @throws Exception
     */    
    public String supprimerUnCommentaire() throws Exception {
    	
    	int idCom = Integer.parseInt(idCommentaire);
    	CommentairesEntity com = appliService.recupererCommentairesDemandeByID(idCom);

    	appliService.supprimerCommentaire(idCom);
    	CPDemandeEntity d = com.getCPDemandeCommentaire();

    	System.out.println("ID 3 de la demande renvoyé : " + d.getIdentifiantCPDemande());
    	
    	this.idDemande = String.valueOf(d.getIdentifiantCPDemande());
    	
    	
    	initialiser();
    	//initialiser2(d.getIdentifiantCPDemande());
    	return SUCCESS;
    }
    
    
    public String ajouterUnCommentaire() throws Exception {
    	
    	int idCPDemande = Integer.parseInt(idDemande);
    	CPDemande = appliService.recupererCPDemandeById(idCPDemande);
    	
    	// PersonneEntity p = new AdministrateurEntity(); // on ne peut pas encore récupérer l'auteur de la demande
        PersonneEntity personne = appliService.recupererPersonne(SecurityContextHolder.getContext().getAuthentication().getName());
        if (!CommentaireDemande.equals("")) {
        	appliService.ajouterUnCommentaire(CommentaireDemande, personne, CPDemande);
        	appliService.modifierDateDernierEtatDemande(idCPDemande);
        }
    	
    	initialiser();
    	//initialiser2(d.getIdentifiantCPDemande());
    	return SUCCESS;
    }

    /**
     * Modification et sauvegarde des etats des etapes de la demande
     * 
     * @return
     * @throws Exception
     */
    public String modifierEtatConsultDemande() throws Exception {

    // Si plusieurs état dans le tableau, this.etat va recuperer le tout sous forme de "etat1, etat2, etat3..." donc découpage
       	String lesEtatsAffichés[] = this.etat.split(", ");
       	String lesEtapesAffichés[] = this.EtapeChoisit.split(", ");
       	String idDeLaDemande[] = idDemande.split(", ");
       	int convertEtapInt;
       	
       	int idCPDemande = Integer.parseInt(idDeLaDemande[0]);
       	
       	CPDemandeWithEtape = appliService.recuperCPDemandeWithEtapes(idCPDemande);
       	int taille = CPDemandeWithEtape.getEtapesCPDemande().size();
       	int j =0;
      /*  for (Iterator i = ModifierEtatConsult.keySet().iterator(); i.hasNext();) {*/
       	for (int i=0; i<taille;i++) {
        	convertEtapInt = Integer.parseInt(lesEtapesAffichés[j]);
          //  int idEtape = Integer.valueOf((String) i.next());
            System.out.println("tessssssssst " +lesEtatsAffichés[j] +" zzzzzzz "+ convertEtapInt);
            appliService.modifierEtatCPEtape(convertEtapInt, lesEtatsAffichés[j]);
            appliService.modifierDateDernierEtatDemande(idCPDemande);
            j++;
        }
        // remplir la jsp après modification des etats de l'étape
        initialiser();
        
        return SUCCESS;
    }

    /**
     * Modification et sauvegarde des etats des etapes de la demande
     * 
     * @return
     * @throws Exception
     */
    public String modifierEtatDeDemande() throws Exception {

        int idDemande=0;
        int cpt=0;
        for (Iterator i = modifierEtatDeDemande.keySet().iterator(); i.hasNext();) {
            idDemande = Integer.valueOf((String) i.next());
            appliService.modifierEtatDemande(idDemande, etatDemande);
            appliService.modifierDateDernierEtatDemande(idDemande);
            
            // workflow 7
            
            if (etatDemande.equals("Ré-ouverte")){
            	this.CPDemandeWithEtape = appliService.recuperCPDemandeWithEtapes(idDemande);
            	
            	for(CPEtapeEntity e : this.CPDemandeWithEtape.getEtapesCPDemande() ){
            		appliService.modifierEtatCPEtape(e.getIdentifiantCPEtape(), "En attente");
            	}
            	
            	
            	for (CPPointDeControleEntity pc :  appliService.recupererCPPointControleDemande2(idDemande)) {
            		
            		if (pc.getValeurPointDeControle() == "true" || pc.getValeurPointDeControle() == "false") {
            			appliService.modifierValeurPointControle(pc.getIdentifiantCPPointDeControle(), "false");
            		} else {
            			appliService.modifierValeurPointControle(pc.getIdentifiantCPPointDeControle(), "");
            		}
            	}
            }
        }
        initialiser2(idDemande);
        
        return SUCCESS;
    }

	/**
     * Création du fichier xml
     */
    public void creerXML() {
        SauvegardeXML.creerXML(idCPDemande);
    }

    /**
     * Récupération de la demande, ses etats et ses points de contrôle
     * 
     */
    private void initialiser() {
        String k[] = this.idDemande.split(", ");
        this.idDemande = k[0];
        int idCPDemande = Integer.parseInt(idDemande);
        CPDemande = appliService.recupererCPDemandeById(idCPDemande);
        this.reference = CPDemande.getReferenceCPDemande();

        testReference();
        /* Dans CPDemandeWithEtape on va charger les demandes et leurs etapes en même temps */
        CPDemandeWithEtape = appliService.recuperCPDemandeWithEtapes(idCPDemande);
        
        //workflow point 5
        int cpt=0;
        int cpt2=0;
        int cptClose=0;
        for (CPEtapeEntity e : this.CPDemandeWithEtape.getEtapesCPDemande()){
        	if (e.getEtatCPEtape().getNomEtat().equals("En cours de traitement") ||e.getEtatCPEtape().getNomEtat().equals("Close")) {
        		cpt++;
        	}
        	if (e.getEtatCPEtape().getNomEtat().equals("Close")){
        		cptClose++;
        	}
        	cpt2++;
        }
        if (cpt>=1 && cpt < cpt2){
        	EtatEntity ee = new EtatEntity();
        	ee.setNomEtat("En cours de traitement");
        	CPDemande.setEtatCPDemande(ee);
        }
        if (cptClose == cpt2){
        	EtatEntity ee = new EtatEntity();
        	ee.setNomEtat("Close");
        	CPDemande.setEtatCPDemande(ee);
        }
        
        //this.lesetats = appliService.recupererEtat();
        this.lesetats.add("En attente");
        this.lesetats.add("En cours de traitement");
        this.lesetats.add("Close");
        Letats.addAll(appliService.recupererEtat());
        ListPointControle = (List<CPPointDeControleEntity>) appliService.recupererCPPointControleDemande2(Integer.valueOf(idDemande));
        lesCommentaires = appliService.recupererCommentairesDemande(idCPDemande);
    }
    
    private void initialiser2(int idDemande) {

        CPDemande = appliService.recupererCPDemandeById(idDemande);
        this.reference = CPDemande.getReferenceCPDemande();

        testReference();

        CPDemandeWithEtape = appliService.recuperCPDemandeWithEtapes(idDemande);
        this.lesetats.add("En attente");
        this.lesetats.add("En cours de traitement");
        this.lesetats.add("Close");
        Letats.addAll(appliService.recupererEtat());
        ListPointControle = (List<CPPointDeControleEntity>) appliService.recupererCPPointControleDemande2(Integer.valueOf(idDemande));
        lesCommentaires = appliService.recupererCommentairesDemande(idDemande);
    }

    public void testReference() {
        if (this.reference.matches("^[0-9]+")) {
            this.typeReference = true;
        } else {
            this.typeReference = false;
        }

    }

}